﻿#region License
/* Copyright (C) 2009 Tim Coulter
 * 
 * This file is part of ExtremeML.
 * 
 * ExtremeML is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public
 * License, as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
 * the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
*/
#endregion

using System;
using DocumentFormat.OpenXml.Spreadsheet;

namespace ExtremeML.Spreadsheet
{
	// This is a partial class that adds custom functionality to its auto-generated partner.
	public sealed partial class CellWrapperCollection
	{
		#region Custom Properties

		/// <summary>
		/// Gets the containing <see cref="RowWrapper"/>.
		/// </summary>
		public RowWrapper Row
		{
			get { return (RowWrapper)Parent; }
		}

		/// <summary>
		/// Gets the containing <see cref="WorksheetWrapper"/>.
		/// </summary>
		public WorksheetWrapper Worksheet
		{
			get { return ((WorksheetWrapper)Parent.Parent.Parent.Parent); }
		}

		#endregion
		#region Custom Methods

		/// <summary>
		/// Returns whether this collection contains a cell wrapper having the specified cell index.
		/// </summary>
		/// <param name="index">The zero-based row index of the target cell.</param>
		/// <returns>A value that indicates whether a matching cell wrapper exists.</returns>
		internal bool Contains(
			int index)
		{
			return Find(index) != null;
		}

		/// <summary>
		/// Returns the wrapper for the cell having the specified index.
		/// </summary>
		/// <param name="index">The zero-based index of the target cell.</param>
		/// <returns>A <see cref="CellWrapper"/> that matches the specified index. <c>null</c> if no match is found.</returns>
		internal CellWrapper Find(
			int index)
		{
			if (index < 0) throw new ArgumentOutOfRangeException("index");

			// The index of an item in its collection is not necessarily the
			// same as its ColumnIndex (due to sparse markup optimization). It
			// is therefore essential to retrieve matches using comparison.
			return Items.Find(item => item.CellAddress.ColumnIndex == index);
		}

		/// <summary>
		/// Returns a <see cref="CellWrapper"/> that wraps a new <see cref="Cell"/>.
		/// </summary>
		/// <param name="index">The zero-based cell index of the cell wrapper to create.</param>
		/// <returns>A new instance of <see cref="CellWrapper"/>.</returns>
		internal CellWrapper Add(
			int index)
		{
			if (index < 0) throw new ArgumentOutOfRangeException("index");

			var result = Add();
			result.CellAddress.RowIndex = Row.RowSpan.Begin;
			result.CellAddress.ColumnIndex = index;
			result.CellAddress.RowAbsolute = false;
			result.CellAddress.ColumnAbsolute = false;
			result.Activate();
			return result;
		}

		#endregion
		#region Overrides

		/// <summary>
		/// Performs housekeeping and validation of a requested deletion.
		/// </summary>
		protected override void OnCustomRemoved(
			CellWrapper member)
		{
			// When the last cell in a row is deleted the row itself can be deleted
			if (Items.Count == 0)
			{
				Row.Remove();
			}
		}

		/// <summary>
		/// Implements custom persistence functionality.
		/// </summary>
		protected override void OnCustomRecomposing()
		{
			// The row list must be in index sequence before persistence
			Items.Sort((a, b) => a.CellAddress.CompareTo(b.CellAddress));
		}

		#endregion
		#region Implementation Methods


		#endregion
		#region Static Methods


		#endregion
	}
}
